﻿using System;
using System.Collections.Generic;
using System.Linq;

using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.Util;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Hamster.K3Cloud.WebAPI.ServerExtend
{
    /// <summary>
    /// 参数格式化
    /// </summary>
    public class Formater
    {
        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public static string Query(Parameter parameter)
        {
            RequestQuery param = new RequestQuery();
            param.FormId = parameter.NextFormId;
            param.FieldKeys = "";
            param.FilterString = "";
            param.OrderString = "";

            return JsonConvert.SerializeObject(param);
        }

        /// <summary>
        /// 删除接口参数
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public static string Delete(Parameter parameter)
        {
            RequestDelete param = new RequestDelete();
            param.Numbers = new JArray();
            param.CreateOrgId = 0;
            param.NetworkCtrl = true;
            param.Ids = "";

            param.Numbers = formatNumbers(parameter);
            if (param.Numbers.Count() == 0)
            {
                param.Ids = formatFID(parameter);
            }

            return JsonConvert.SerializeObject(param);
        }

        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public static string Create(Parameter parameter)
        {
            RequestSave param = new RequestSave();
            param.NeedUpDateFields = new JArray();
            param.NeedReturnFields = new JArray();
            param.IsDeleteEntry = true;
            param.SubSystemId = "";
            param.IsVerifyBaseDataField = false;
            param.IsEntryBatchFill = true;
            param.ValidateFlag = true;
            param.NumberSearch = true;
            param.Model = new JObject();

            param.NeedReturnFields = NeedReturnFields();
            JArray entryData = parameter.Model[parameter.NextEntryKey] as JArray;
            int entryDataCount = entryData.Count();

            // 清理明细数据中的FSrcEntryID
            for (int i = 0; i < entryDataCount; i++)
            {
                JObject item = entryData[i] as JObject;
                item.Remove(Defineds.FSrcEntryID);
                item.Remove("FEntryID");
                entryData[i] = item;
            }

            return JsonConvert.SerializeObject(param);
        }

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public static string Update(Parameter parameter)
        {
            RequestSave param = new RequestSave();
            param.NeedUpDateFields = new JArray();
            param.NeedReturnFields = new JArray();
            param.IsDeleteEntry = false;
            param.SubSystemId = "";
            param.IsVerifyBaseDataField = false;
            param.IsEntryBatchFill = true;
            param.ValidateFlag = true;
            param.NumberSearch = true;
            param.Model = new JObject();

            if ((parameter.Model.Property("FID") == null || parameter.Model["FID"] == null) && (parameter.Model.Property("FBillNo") == null || parameter.Model["FBillNo"] == null))
            {
                return JsonConvert.SerializeObject(param);
            }

            if (parameter.Model.Property(parameter.NextEntryKey) == null || parameter.Model[parameter.NextEntryKey] == null)
            {
                return JsonConvert.SerializeObject(param);
            }

            param.NeedReturnFields = NeedReturnFields();

            // 组织需要更新的字段
            JArray needUpDateFields = new JArray();
            JArray entryData = parameter.Model[parameter.NextEntryKey] as JArray;
            foreach (JProperty item in parameter.Model.Properties())
            {
                if (item.Name != "FID" || item.Name != parameter.NextEntryKey)
                {
                    needUpDateFields.Add(item.Name);
                }
            }
            needUpDateFields.Add(parameter.NextEntryKey);
            JObject entryDataZero = entryData[0] as JObject;
            foreach (JProperty item in entryDataZero.Properties())
            {
                if (item.Name != "FID" && item.Name != "FBillNo" && item.Name != parameter.NextEntryKey)
                {
                    needUpDateFields.Add(item.Name);
                }
            }

            // 替换FSrcEntryID为FEntryID
            int entryDataCount = entryData.Count();
            for (int i = 0; i < entryDataCount; i++)
            {
                JObject item = entryData[i] as JObject;
                item.Add(new JProperty("FEntryID", Convert.ToInt64(item[Defineds.FSrcEntryID])));
            }

            param.NeedUpDateFields = needUpDateFields;
            param.Model = parameter.Model;
            return JsonConvert.SerializeObject(param);
        }

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public static string Update(Parameter parameter, DynamicObjectCollection entryIds)
        {
            RequestSave param = new RequestSave();
            param.NeedUpDateFields = new JArray();
            param.NeedReturnFields = new JArray();
            param.IsDeleteEntry = false;
            param.SubSystemId = "";
            param.IsVerifyBaseDataField = false;
            param.IsEntryBatchFill = true;
            param.ValidateFlag = true;
            param.NumberSearch = true;
            param.Model = new JObject();
            
            if (entryIds.Count() == 0)
            {
                return JsonConvert.SerializeObject(param);
            }

            if ((parameter.Model.Property("FID") == null || parameter.Model["FID"] == null) && (parameter.Model.Property("FBillNo") == null || parameter.Model["FBillNo"] == null))
            {
                return JsonConvert.SerializeObject(param);
            }

            if (parameter.Model.Property(parameter.NextEntryKey) == null || parameter.Model[parameter.NextEntryKey] == null)
            {
                return JsonConvert.SerializeObject(param);
            }

            long FID = 0;

            // 需要返回的字段
            param.NeedReturnFields = NeedReturnFields();

            // 组织需要更新的字段
            JArray needUpDateFields = new JArray();
            JArray entryData = parameter.Model[parameter.NextEntryKey] as JArray;
            foreach (JProperty item in parameter.Model.Properties())
            {
                if (item.Name == "FID" && Convert.ToInt64(item.Value) > 0)
                {
                    FID = Convert.ToInt64(item.Value);
                }

                if (item.Name != "FID" || item.Name != parameter.NextEntryKey)
                {
                    needUpDateFields.Add(item.Name);
                }
            }

            needUpDateFields.Add(parameter.NextEntryKey);
            JObject entryDataZero = entryData[0] as JObject;
            foreach (JProperty item in entryDataZero.Properties())
            {
                if (item.Name != Defineds.FSrcEntryID || item.Name != "FEntryID")
                {
                    needUpDateFields.Add(item.Name);
                }
            }

            // 替换FSrcEntryID为FEntryID
            int entryDataCount = entryData.Count();
            for (int i = 0; i < entryDataCount; i++)
            {
                JObject item = entryData[i] as JObject;
                foreach (var idValue in entryIds)
                {
                    if (Convert.ToString(item[Defineds.FSrcEntryID]) == Convert.ToString(idValue["FSID"]))
                    {
                        if (FID <= 0)
                        {
                            FID = Convert.ToInt64(idValue["FID"]);
                        }

                        item.Add(new JProperty("FEntryID", Convert.ToInt64(idValue["FENTRYID"])));
                    }
                }
                item.Remove(Defineds.FSrcEntryID);
                entryData[i] = item;
            }

            param.NeedUpDateFields = needUpDateFields;
            param.Model = parameter.Model;

            if (parameter.Model.Property("FID") == null)
            {
                parameter.Model.Add(new JProperty("FID", FID));
            }

            return JsonConvert.SerializeObject(param);
        }

        /// <summary>
        /// 提交
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public static string Submit(Parameter parameter)
        {
            RequestSubmit param = new RequestSubmit();
            param.CreateOrgId = 0;
            param.Numbers = new JArray();
            param.Ids = "";
            param.SelectedPostId = 0;
            param.NetworkCtrl = true;

            param.Numbers = formatNumbers(parameter);
            if (param.Numbers.Count() == 0)
            {
                param.Ids = formatFID(parameter);
            }

            return JsonConvert.SerializeObject(param);
        }

        /// <summary>
        /// 审核
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public static string Audit(Parameter parameter)
        {
            RequestAudit param = new RequestAudit();
            param.CreateOrgId = 0;
            param.Numbers = new JArray();
            param.Ids = "";
            param.InterationFlags = "";
            param.NetworkCtrl = true;

            param.Numbers = formatNumbers(parameter);
            if (param.Numbers.Count() == 0)
            {
                param.Ids = formatFID(parameter);
            }

            return JsonConvert.SerializeObject(param);
        }

        /// <summary>
        /// 反审核
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public static string UnAudit(Parameter parameter)
        {
            RequestUnAudit param = new RequestUnAudit();
            param.CreateOrgId = 0;
            param.Numbers = new JArray();
            param.Ids = "";
            param.InterationFlags = "";
            param.NetworkCtrl = true;

            param.Numbers = formatNumbers(parameter);
            if (param.Numbers.Count() == 0)
            {
                param.Ids = formatFID(parameter);
            }

            return JsonConvert.SerializeObject(param);
        }

        /// <summary>
        /// 下推
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public static string Push(Parameter parameter)
        {
            RequestPush param = new RequestPush();
            param.Ids = "";
            param.Numbers = new JArray();
            param.EntryIds = "";
            param.RuleId = "";
            param.TargetBillTypeId = "";
            param.TargetOrgId = 0;
            param.TargetFormId = "";
            param.IsEnableDefaultRule = false;
            param.IsDraftWhenSaveFail = false;
            param.CustomParams = new JObject();

            param.Numbers = formatNumbers(parameter);
            if (param.Numbers.Count() == 0)
            {
                param.Ids = formatFID(parameter);
            }

            List<string> entryIds = new List<string>();
            JArray entryData = parameter.Model[parameter.NextEntryKey] as JArray;
            foreach (JObject entry in entryData)
            {
                foreach (JProperty item in entry.Properties())
                {
                    if (item.Name == Defineds.FSrcEntryID)
                    {
                        entryIds.Add(Convert.ToString(item.Value));
                    }
                }
            }

            if (entryIds.Count() > 0)
            {
                param.EntryIds = string.Join(",", entryIds);
            }

            param.RuleId = parameter.RuleId;
            param.TargetFormId = parameter.NextFormId;

            return JsonConvert.SerializeObject(param);
        }

        /// <summary>
        /// 格式化单据编号
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        private static JArray formatNumbers(Parameter parameter)
        {
            JArray jNumbers = new JArray();
            if (parameter.Model.Property("FBillNo") == null || parameter.Model["FBillNo"] == null)
            {
                return jNumbers;
            }

            string numbers = Convert.ToString(parameter.Model["FBillNo"]);
            if (numbers.IsEmpty())
            {
                return jNumbers;
            }

            if (numbers.IndexOf(",") > 0)
            {
                string[] numberList = numbers.Split(',');
                foreach (string number in numberList)
                {
                    jNumbers.Add(new JValue(number.Trim()));
                }

                return jNumbers;
            }

            jNumbers.Add(new JValue(numbers));
            return jNumbers;
        }

        /// <summary>
        /// 格式化单据内码
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        private static string formatFID(Parameter parameter)
        {
            string ids = "";
            if (parameter.Model.Property("FID") == null || parameter.Model["FID"] == null)
            {
                return ids;
            }

            return Convert.ToString(parameter.Model["FID"]);
        }

        /// <summary>
        /// 需要返回的字段
        /// </summary>
        /// <returns></returns>
        private static JArray NeedReturnFields()
        {
            JArray needReturnFields = new JArray
            {
                new JValue("FID"),
                new JValue("FBillNo")
            };
            return needReturnFields;
        }

        /// <summary>
        /// 格式化WebAPI返回结果
        /// </summary>
        /// <param name="res"></param>
        /// <returns></returns>
        public static ResponseData ConvertWebAPIResult(object res)
        {
            Dictionary<string, object> _res = res as Dictionary<string, object>;
            Dictionary<string, object> result = _res["Result"] as Dictionary<string, object>;
            ResponseData responseData = new ResponseData();
            responseData.Result = ConvertWebAPIResultResponseDataResult(result);
            return responseData;
        }

        /// <summary>
        /// 格式化WebAPI返回结果中的Result
        /// </summary>
        /// <param name="res"></param>
        /// <returns></returns>
        public static ResponseDataResult ConvertWebAPIResultResponseDataResult(object res)
        {
            Dictionary<string, object> result = res as Dictionary<string, object>;
            ResponseDataResult responseDataResult = new ResponseDataResult();
            if (result.ContainsKey("Id") && result["Id"] != null)
            {
                responseDataResult.ID = Convert.ToInt64(result["Id"]);
            }

            if (result.ContainsKey("Number") && result["Number"] != null)
            {
                responseDataResult.Number = Convert.ToString(result["Number"]);
            }

            responseDataResult.ResponseStatus = ConvertWebAPIResultData(result["ResponseStatus"]);
            if (result.ContainsKey("NeedReturnData") && result["NeedReturnData"] != null)
            {
                responseDataResult.NeedReturnData = result["NeedReturnData"] as JArray;
            }
            
            return responseDataResult;
        }

        /// <summary>
        /// 格式化WebAPI返回结果中的结果数据
        /// </summary>
        /// <param name="res"></param>
        /// <returns></returns>
        public static ResponseDataResultStatus ConvertWebAPIResultData(object res)
        {
            Dictionary<string, object> result = res as Dictionary<string, object>;
            ResponseDataResultStatus responseDataResult = new ResponseDataResultStatus();
            
            if (result.ContainsKey("IsSuccess"))
            {
                responseDataResult.IsSuccess = Convert.ToBoolean(result["IsSuccess"]);
            }
            
            if (result.ContainsKey("MsgCode"))
            {
                responseDataResult.MsgCode = Convert.ToInt64(result["MsgCode"]);
            }
            
            if (result.ContainsKey("ErrorCode"))
            {
                responseDataResult.ErrorCode = Convert.ToInt64(result["ErrorCode"]);
            }

            responseDataResult.Errors = ConvertWebAPIResultErrors(result["Errors"]);
            responseDataResult.SuccessEntitys = ConvertWebAPIResultSuccessEntitys(result["SuccessEntitys"]);
            responseDataResult.SuccessMessages = ConvertWebAPIResultSuccessMessages(result["SuccessMessages"]);
            return responseDataResult;
        }

        /// <summary>
        /// 格式化WebAPI返回结果中的错误信息
        /// </summary>
        /// <param name="res"></param>
        /// <returns></returns>
        public static List<ResponseDataResultErrors> ConvertWebAPIResultErrors(object res)
        {
            if (res == null)
            {
                return null;
            }

            List<object> result = res as List<object>;
            List<ResponseDataResultErrors> responseDataResultErrors = new List<ResponseDataResultErrors>();
            foreach (object item in result)
            {
                ResponseDataResultErrors value = new ResponseDataResultErrors();
                Dictionary<string, object> _item = item as Dictionary<string, object>;
                value.DIndex = Convert.ToInt64(_item["DIndex"]);
                value.FieldName = Convert.ToString(_item["FieldName"]);
                value.Message = Convert.ToString(_item["Message"]);
                responseDataResultErrors.Add(value);
            }

            return responseDataResultErrors;
        }

        /// <summary>
        /// 格式化WebAPI返回结果中的成功的明细
        /// </summary>
        /// <param name="res"></param>
        /// <returns></returns>
        public static List<ResponseDataResultSuccessEntitys> ConvertWebAPIResultSuccessEntitys(object res)
        {
            if (res == null)
            {
                return null;
            }

            List<object> result = res as List<object>;
            List<ResponseDataResultSuccessEntitys> responseDataResultSuccessEntitys = new List<ResponseDataResultSuccessEntitys>();
            foreach (object item in result)
            {
                ResponseDataResultSuccessEntitys value = new ResponseDataResultSuccessEntitys();
                Dictionary<string, object> _item = item as Dictionary<string, object>;
                value.DIndex = Convert.ToInt64(_item["DIndex"]);
                value.Id = Convert.ToInt64(_item["Id"]);
                value.Number = Convert.ToString(_item["Number"]);
                responseDataResultSuccessEntitys.Add(value);
            }

            return responseDataResultSuccessEntitys;
        }

        /// <summary>
        /// 格式化WebAPI返回结果中的成功的信息
        /// </summary>
        /// <param name="res"></param>
        /// <returns></returns>
        public static List<ResponseDataResultSuccessMessages> ConvertWebAPIResultSuccessMessages(object res)
        {
            if (res == null)
            {
                return null;
            }

            List<object> result = res as List<object>;
            List<ResponseDataResultSuccessMessages> responseDataResultSuccessMessages = new List<ResponseDataResultSuccessMessages>();
            foreach (object item in result)
            {
                ResponseDataResultSuccessMessages value = new ResponseDataResultSuccessMessages();
                Dictionary<string, object> _item = item as Dictionary<string, object>;
                value.DIndex = Convert.ToInt64(_item["DIndex"]);
                value.FieldName = Convert.ToString(_item["FieldName"]);
                value.Message = Convert.ToString(_item["Message"]);
                responseDataResultSuccessMessages.Add(value);
            }

            return responseDataResultSuccessMessages;
        }
    }
}
